/*
 * colas_peticiones
 *
 * Implementaciones de las colas de peticiones y los algoritmos de distribución
 * de las colas en los distintos discos.
 *
 */


#ifndef COLAS_PETICIONES_H_
#define COLAS_PETICIONES_H_

#include <stdlib.h>
#include <stdint.h>
#include <semaphore.h>
#include <error.h>
//#include <pthread.h>

#include "collections/list.h"
#include "collections/queue.h"
#include "nipc.h"
#include "log.h"
#include "config.h"

/******************************************
Escructuras para colas de  los discos
 *****************************************/

typedef struct {
	uint64_t id_peticion;
	uint8_t tipo;
	T_MENSAJE *mensaje;
} REG_COLA_PETICION;

typedef struct {
	uint8_t id_disco;
	t_queue* cola_pedidos;
	sem_t contador_elem;
	sem_t pedidos_discos; //para sincronizar los pedidos del filesystem
	sem_t mutex;		  //bloquea el socket hasta que atienda 1 PEDIDO(F o P)
	sem_t flag;			  //Indica si hay pedidos en cola_disco 1= tiene
	char flag_sinc;       //sincroniza los pedidos del planificador, sin atender los del filesystem
	char flag_fin;		  //Indica si el disco termino de ejecutarse 1= si, 0=no
	sem_t rep_pedidos_pen;//Indica si se debe repartir los pedidos pendientes del disco caido
	pthread_t thread_id;
	int socket;
} REG_DISCO;

REG_COLA_PETICION* generarPeticion(uint8_t tipo_msg, T_MENSAJE* mensaje);
void eliminarPeticion(REG_COLA_PETICION*);

/******************************************
 Escructuras para colas de proceso RAID
 *****************************************/

typedef struct {
	int sock; //modificar el tipo
	uint64_t id_peticion;
} REG_COLA_RAID;

t_queue* cola_lectura;
t_queue* cola_escritura;
uint64_t contador_peticiones;
t_list* lista_peticiones_raid;
t_list* lista_discos;
uint8_t disco_actual;

sem_t mutex_id_peticion;
int buffer_id_peticion;

void insertarEnColasRaid(REG_COLA_PETICION* peticion, int sock);
void distribuirPeticiones();
void distribuirEscrituraEntreDiscos(REG_COLA_PETICION* peticion);
void distribuirLecturaEntreDiscos(REG_COLA_PETICION* peticion);
void inicializar();
void nuevoDisco(int socket, uint8_t id_disco);
int closureColaPeticion(void* data);
int buscaSocketRta(uint64_t id_peticion);


#endif /* NIPC_H_ */
